// run: $exec < input
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <utility>
#include <functional>

struct node { int to, cost; };

int const inf = 1 << 29;
int const maxn = 100;

std::vector<node> graph[maxn];
typedef std::vector<node>::iterator edge_iter;
bool vis[maxn];

int n, m, k, s, t;

void add_edge(int x, int y, int z)
{
	graph[x].push_back({y, z});
}

int dijkstra(int source, int target)
{
	int num = n + 4; // tot vertices FIXME
	int dist[num];
	std::fill(dist, dist + num, inf);
	dist[source] = 0;
	typedef std::pair<int, int> cost_end;
	std::priority_queue<cost_end, std::vector<cost_end>, std::greater<cost_end> > pq;
	pq.push(std::make_pair(0, source));
	while (!pq.empty()) {
		cost_end tmp = pq.top(); pq.pop();
		int u = tmp.second;
		if (dist[u] < tmp.first) continue;

		for (edge_iter edge = graph[u].begin(); edge != graph[u].end(); ++edge) {
			int v = edge->to, c = edge->cost;
			if (vis[v]) continue;
			if (dist[v] > dist[u] + c) {
				dist[v] = dist[u] + c;
				pq.push(std::make_pair(dist[v], v));
			}
		}
	}
	return dist[target];
}

void init()
{
	for (int i = 0; i <= n; i++) graph[i].clear();
}

int main()
{
	std::ios::sync_with_stdio(false);
	while (std::cin >> n >> m && (n || m)) {
		init();
		for (int i = 0; i < m; i++) {
			int x, y, z;
			std::cin >> x >> y >> z;
			add_edge(x, y, z);
			add_edge(y, x, z);
		}

		int ans = 0;
		bool has_sol = true;
		for (int i = 2; i < n; i++) {
			vis[i] = true;
			int tmp = dijkstra(1, n);
			if (tmp >= inf) {
				has_sol = false;
				break;
			}
			ans = std::max(ans, tmp);
			vis[i] = false;
		}
		if (has_sol) std::cout << ans << "\n";
		else std::cout << "Inf\n";
	}
}

